package com.gopay.gass.service.impl;

import com.gopay.common.util.HttpTransport;
import com.gopay.gass.constants.NotifyStatus;
import com.gopay.gass.constants.RespType;
import com.gopay.gass.domain.GassMainOrder;
import com.gopay.gass.service.GassNotifyService;
import com.gopay.gass.service.GassOrderService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.naming.CommunicationException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by HJY on 2015/3/22.
 * 异步通知
 */
@Service("gassNotifyService")
public class GassNotifyServiceImpl implements GassNotifyService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource(name = "gassOrderService")
    private GassOrderService gassOrderService;

    //异步通知的最大次数
    public static final int MAX_NOTIFY_COUNT = 5;

    @Override
    public void gassNotify() {
        List<GassMainOrder> orderList = gassOrderService.getNotifyOrderList();
        if(orderList != null && orderList.size()>0){
            for(GassMainOrder order : orderList){
                gassNotify(order);
            }
        }
    }

    @Override
    public void gassNotify(String gassId) {
        GassMainOrder order = gassOrderService.getMainOrder(gassId);
        gassNotify(order);
    }

    private void gassNotify(GassMainOrder order){
        if(order != null
                && StringUtils.equals(order.getRespType(), RespType.Asyn.toString())
                && (StringUtils.equals(order.getNotifyStatus(), NotifyStatus.NO.toString()))
                && StringUtils.isNotEmpty(order.getNotifyUrl())
                && order.getNotifyCount() < MAX_NOTIFY_COUNT){
            //通知
            execute(order);
        }
    }



    public void execute(GassMainOrder order){
        ExecutorService executorService = Executors.newFixedThreadPool(30);
        NotifyRunnable nmr = new NotifyRunnable(order);
        executorService.execute(nmr);
    }

    class NotifyRunnable implements Runnable{
        private  GassMainOrder order;
        public NotifyRunnable(GassMainOrder order){
            this.order = order;
        }
        @Override
        public void run() {
           send(order);
        }

        private void send(GassMainOrder order){
            logger.info(String.format("notify start url:%s,gopayOrderId:%s,resultCode:%s",order.getNotifyUrl(),order.getGopayOrderId(),order.getStlmStatus()));
            NotifyStatus notifyStatus = NotifyStatus.NO;
            try {
                HttpTransport httpTransport = new HttpTransport();
                httpTransport.setSendEncoding("GBK");
                httpTransport.setUrl(order.getNotifyUrl());
                Map<String, String> params = new HashMap<String, String>();
                params.put("gopayOrderId",order.getGopayOrderId());
                params.put("responseId",order.getGassId());
                params.put("resultCode",order.getStlmStatus()+"");
                int res = httpTransport.submit_backCode(params);
                if(res == 200){
                    notifyStatus = NotifyStatus.YES;
                    logger.info(String.format("notify end success  gopayOrderId:%s ", order.getGopayOrderId()));
                }else{
                    logger.info(String.format("notify end failed  gopayOrderId:%s ", order.getGopayOrderId()));
                }
                order.setNotifyCount(order.getNotifyCount()+1);
                order.setNotifyTm(new Date());
                order.setNotifyStatus(notifyStatus.toString());
                gassOrderService.updateMainOrder(order);
            } catch (CommunicationException e) {
                e.printStackTrace();
            }
        }
    }
}
